/**
 * File: main.cpp
 * Created Time: 2024-12-30
 * Author: chugehehe (3321592850@qq.com)
 */


#include "MyTask.h"
#include "ThreadPool.h"
#include "MySQLConnection.h"
#include <memory>
#include <chrono>
#include <iostream>
#include <functional>
#include <vector>

using std::cout;
using std::endl;
using std::shared_ptr;
using std::unique_ptr;  
using std::vector;
using std::mutex;
using std::condition_variable;
using std::string;
using std::cerr;

// 定义一个数据库任务类
class DatabaseTask : public MyTask {
public:
    DatabaseTask(ThreadPool& pool, const std::string& query)
        : pool(pool), query(query) {}

    void process() override {
        shared_ptr<MySQLConnection> conn = nullptr; // 声明连接
        try {
            conn = pool.getConnection(); // 从线程池的连接池获取连接
            std::cout << "Executing update: " << query << std::endl; // 打印正在执行的更新
            conn->update(query); // 执行更新
            std::cout << "Update executed successfully." << std::endl; // 更新成功执行
        } catch (const sql::SQLException &e) {
            std::cerr << "SQL Error: " << e.what() << std::endl;
            std::cerr << "Error Code: " << e.getErrorCode() << std::endl;
            std::cerr << "SQL State: " << e.getSQLState() << std::endl;
        } catch (const std::exception &e) {
            std::cerr << "Error: " << e.what() << std::endl;
        }

        // Ensure the connection is released
        if (conn) {
            pool.releaseConnection(conn); // Release the connection
        }
    }

private:
    ThreadPool& pool; // 引用线程池
    std::string query; // 查询字符串
};

// 定义一个查询任务类
class QueryTask : public MyTask {
public:
    QueryTask(ThreadPool& pool, const std::string& query)
        : pool(pool), query(query) {}

    void process() override {
        shared_ptr<MySQLConnection> conn; // 声明连接
        try {
            conn = pool.getConnection(); // 从线程池的连接池获取连接
            std::cout << "Executing query: " << query << std::endl; // 打印正在执行的查询
            conn->query(query); // 执行查询并获取结果集


            std::cout << "Query executed successfully." << std::endl; // 查询成功执行
        } catch (const sql::SQLException &e) {
            std::cerr << "SQL Error: " << e.what() << std::endl;
            std::cerr << "Error Code: " << e.getErrorCode() << std::endl;
            std::cerr << "SQL State: " << e.getSQLState() << std::endl;
        } catch (const std::exception &e) {
            std::cerr << "Error: " << e.what() << std::endl;
        }

        // Ensure the connection is released
        if (conn) {
            pool.releaseConnection(conn); // Release the connection
        }
    }

private:
    ThreadPool& pool; // 引用线程池
    std::string query; // 查询字符串
};

void test()
{
    // 记录程序开始时间
    auto total_start = std::chrono::high_resolution_clock::now();

    ConnectionPool dbPool(2, "127.0.0.1", "root", "1234", "test"); // 创建连接池
    ThreadPool pool(4, 100, &dbPool); // 创建线程池，传递连接池引用
    pool.start(); // 启动线程池

    // 创建数据库更新任务
    vector<unique_ptr<MyTask>> tasks;
    for (int i = 0; i < 5; ++i) {
        tasks.emplace_back(std::make_unique<DatabaseTask>(pool, "INSERT INTO user (name, email) VALUES ('用户" + std::to_string(i) + "', 'user" + std::to_string(i) + "@example.com')"));
    }

    // 创建查询任务
    tasks.emplace_back(std::make_unique<QueryTask>(pool, "SELECT * FROM user"));

    // 将任务添加到线程池
    for (auto& task : tasks) {
        pool.addTask(std::bind(&MyTask::process, task.get()));
    }

    // 等待所有任务完成并停止线程池
    pool.stop();

    // 记录程序结束时间
    auto total_end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> total_duration = total_end - total_start;
    cout << "总执行时间: " << total_duration.count() << " 秒" << endl;
}

int main()
{
    test();
    return 0;
}